#include "qpc.h"  /* QP/C framework/RTOS */
#include "bsp.h"  /* Board Support Package */

/* The Blinky thread =======================================================*/
static QXThread l_blinky;  /* TCB for the Blinky thread */
static uint64_t blinkyStackSto[64]; /* stack for the Blinky thread */
static void Blinky_run(QXThread * const me); /* thread function prototype */
static void Blinky_run(QXThread * const me) { /* thread function definition */
    (void)me;
    while (1) {
        BSP_ledGreenOn();
        QXThread_delay(BSP_TICKS_PER_SEC / 4U );  /* BLOCK */
        BSP_ledGreenOff();
        QXThread_delay(BSP_TICKS_PER_SEC * 3U / 4U);  /* BLOCK */
    }
}

/* The SW1 thread ==========================================================*/
static QXThread l_sw1;  /* TCB for the SW1 thread */
static uint64_t sw1StackSto[64]; /* stack for the SW1 thread */
QXSemaphore g_sw1Sema;
static void SW1_run(QXThread * const me); /* thread function prototype */
static void SW1_run(QXThread * const me) { /* thread function definition */
    (void)me;
    while (1) {
        QXSemaphore_wait(&g_sw1Sema, QXTHREAD_NO_TIMEOUT);
        BSP_ledBlueOn();
        QXThread_delay(BSP_TICKS_PER_SEC / 2U );  /* BLOCK */
        BSP_ledBlueOff();
    }
}

/* the main function =======================================================*/
int main() {
    QF_init(); /* initialize the framework/RTOS */
    BSP_init(); /* initialize the BSP */

    /* start the Blinky thread */
    QXThread_ctor(&l_blinky, Q_XTHREAD_CAST(&Blinky_run), 0U);
    QXTHREAD_START(&l_blinky,             /* Thread to start */
                  (uint_fast8_t)1,        /* priority of the thread */
                  (QEvt *)0,              /* message queue storage (not used) */
                  0,                      /* queue length [events] (not used) */
                  blinkyStackSto,         /* stack storage */
                  sizeof(blinkyStackSto), /* stack size [bytes] */
                  (QEvt *)0);             /* initialization event (not used) */

    /* start the SW1 thread */
    QXThread_ctor(&l_sw1, Q_XTHREAD_CAST(&SW1_run), 0U);
    QXTHREAD_START(&l_sw1,                /* Thread to start */
                  (uint_fast8_t)2,        /* priority of the thread */
                  (QEvt *)0,              /* message queue storage (not used) */
                  0,                      /* queue length [events] (not used) */
                  sw1StackSto,            /* stack storage */
                  sizeof(sw1StackSto),    /* stack size [bytes] */
                  (QEvt *)0);             /* initialization event (not used) */

    return QF_run(); /* run the application */
}
